上一篇決定了資料適合放在 RDS、Aurora 還是 DynamoDB,接下來來決定應用程式要怎麼執行與部署。
在 AWS 上,常見的選擇包括:
選擇時可以先問兩件事:應用程式需要怎麼執行?團隊希望自己管理到哪一層?
例如程式是否需要長時間常駐、是否需要控制作業系統、能不能接受事件驅動的執行方式,以及團隊願意承擔多少維運工作,都會影響最後的選擇。
不過,EC2、容器與 Lambda 並不是完全互斥的三個選項,容器可以跑在 EC2 上,也可以透過 Fargate 執行;Lambda 也支援以容器映像檔作為部署套件。
因此這篇真正要比較的不只是「程式放在哪裡」,而是 應用程式的執行方式、部署單位,以及底層基礎設施由誰負責管理。
Amazon EC2 提供虛擬主機,團隊可以選擇作業系統、安裝套件,並自行管理主機上的應用程式與執行環境。
Container(容器) 是封裝與執行應用程式的方式,程式與相依套件被打包成 Container Image(容器映像檔),再由容器執行環境啟動,容器可以跑在 EC2 上,也可以透過 AWS Fargate 執行,將底層主機管理交給 AWS。
AWS Lambda 則由請求或事件觸發函式執行,AWS 會負責配置與管理執行環境,Lambda 也支援使用符合規範的容器映像檔部署。
這篇比較的是以下三種部署模式:
| 比較項目 | EC2 上直接執行程式 | 透過容器平台部署 | Lambda |
|---|---|---|---|
| 部署單位 | 程式、套件、主機設定 | 容器映像檔與執行設定 | ZIP 套件或容器映像檔 |
| 執行方式 | 常駐服務或批次工作 | 常駐服務或一次性任務 | 由請求或事件觸發 |
| 擴展方式 | 增加或調整 EC2 | 增加容器副本或 Task | 依並行需求自動擴展 |
| 作業系統管理 | 團隊負責 | 依 EC2 / Fargate 而異 | AWS 負責 |
| 適合需求 | 需要完整主機控制 | 希望標準化部署與擴展 | 事件驅動、短時間執行 |
EC2 適合需要較高主機控制權的情境。
使用 EC2 時,團隊可以選擇作業系統與 Instance Type,配置儲存與網路,並自行安裝需要的 Runtime、套件與其他軟體,因此如果應用程式本身需要碰到底層主機,EC2 通常會是比較直接的選擇。
以下需求可優先評估 EC2:
但主機控制權也代表更多管理責任,作業系統更新、套件漏洞、磁碟空間、程式健康狀態與容量,都需要團隊處理。
例如流量增加時,可以透過 Auto Scaling 增加 EC2;但新主機仍然必須完成初始化、取得設定並通過健康檢查,才能接手服務。
如果這些步驟仍需要工程師登入後手動操作,即使設定了 Auto Scaling,也很難可靠地擴展。
因此選擇 EC2 後,應確保環境能透過 AMI、啟動腳本或其他自動化流程重新建立,需要管理主機,不等於需要手動管理每台主機。
如果團隊希望把應用程式與相依套件整理成固定的部署單位,而不是依賴每台主機上的環境設定,就可以評估容器。
例如一個 API 需要:
| 內容 | 範例 |
|---|---|
| 語言執行環境 | Python |
| 應用程式框架 | FastAPI |
| 相依套件 | 資料庫驅動、影像處理套件 |
| 程式碼 | API 與商業邏輯 |
這些內容可以一起封裝成 Container Image(容器映像檔),讓開發、測試與正式環境部署相同的建置產物,資料庫位置、環境參數與機密則由外部設定提供。
這樣一來,應用程式的交付單位就變成一份可以重複部署的映像檔。
更新版本時,只需要建立新的 Image,再由平台逐步替換舊容器,這能降低逐台登入修改檔案造成的環境差異,也讓版本更新與回復都有明確的部署產物。
EC2 也能透過 AMI 與自動化達成環境一致性;容器的差異在於,它把應用程式本身與相依套件整理成較獨立的部署單位,不需要和整台主機綁在一起。
容器化之後,還要再決定兩件事:
如果容器跑在自行管理的 EC2 上,團隊仍然需要維護主機與容量;使用 Fargate 可以減少這部分工作,但映像檔、資源配置、網路與應用程式本身仍然需要管理。
例如映像檔內的套件出現漏洞,團隊仍然要更新套件、重新建置並部署新的 Image,平台不會自動替換打包進去的內容。
容器也不會自動解決高可用與資料保存,重要資料應放在外部儲存,健康檢查、擴展規則與部署策略也需要另外設定,單純執行一次 docker run 還不等於完整的正式環境部署。
因此,對已經可以容器化的 API、Worker 或批次工作,如果希望統一部署產物、方便擴展與版本更新,可以優先評估 ECS、EKS 等容器平台,再依主機管理需求選擇 EC2 或 Fargate。
假設網站新增一個功能:使用者把圖片上傳到 S3 後,自動產生縮圖。
這個工作不需要自行維持一個全天候等待圖片的程序,可以讓 S3 上傳事件觸發 Lambda,由函式讀取圖片、產生縮圖,再把結果寫回 S3。
其他常見的觸發方式包括:
| 觸發來源 | 執行工作 |
|---|---|
| S3 物件建立事件 | 產生縮圖、檢查檔案 |
| API Gateway 收到請求 | 執行 API 邏輯 |
| EventBridge Scheduler 排程 | 定期整理資料 |
| SQS 訊息 | 處理佇列中的工作 |
Lambda 會使用可用的執行環境處理請求,需要更多容量時再建立新的環境,並不是每次呼叫都重新建立。
應用程式也不能假設下一次一定會使用相同的執行環境,必要的狀態應保存在資料庫或其他外部服務,本機暫存只能作為可以重新建立的資料。
Concurrency(並行數) 指同一時間正在執行的請求數量。
Lambda 會依同時執行的請求增加執行環境,因此不需要事先維持固定數量的主機,不過擴展仍受到並行配額、函式設定與服務擴展速度等限制。
對流量不固定、事件數量變化明顯,或不希望自行維持常駐運算容量的工作,Lambda 可以減少主機與容量管理。
但擴展後的壓力仍可能往下游傳遞,例如同時執行的函式增加,資料庫可能突然收到更多連線與查詢,Lambda 能擴展,不代表資料庫與外部 API 也能承受相同流量。
本文以一般 Lambda 函式為主要比較範圍,先確認三件事。
第一,單次工作能不能在時間限制內完成。
一般 Lambda 函式的 Timeout 上限是 900 秒,也就是 15 分鐘,如果不可拆分的工作需要 20~40 分鐘,就不適合直接放進這個執行模式。
也不能只看平均時間,大檔案、外部服務延遲與資料量增加,都可能讓工作超時,測試時應涵蓋合理範圍內最大的輸入。
Lambda Managed Instances 的部分非同步與 Event Source Mapping 呼叫有不同的執行時間限制,不列入本文主要比較範圍。
第二,延遲要求能不能接受初始化時間。
Lambda 建立新的執行環境時,需要初始化執行環境與程式,這就是 Cold Start(冷啟動)。
如果 API 對回應時間很敏感,需要測試初始化與擴展時的延遲,必要時評估 Provisioned Concurrency 等預先準備執行環境的方式,並將額外成本納入考量。
第三,重複執行與下游壓力要怎麼處理。
依事件來源與呼叫方式不同,工作可能被重試或重複投遞,程式需要具備 Idempotency(冪等性),讓同一筆工作重複處理時,不會造成重複扣款或建立重複資料。
並行數也應配合下游容量設定,必要時搭配佇列緩衝,避免大量 Lambda 同時執行時直接壓垮資料庫或外部服務。
Lambda 減少了主機維護,但事件處理、錯誤恢復與相依服務容量,仍然需要設計。
因此,以下需求可以優先評估 Lambda:
如果應用程式需要長時間持續運行、依賴固定主機狀態,或單次工作超過一般 Lambda 的執行限制,EC2 或容器平台通常會更適合。
以下用一個假設情境比較。
一個網站目前有三種工作:
團隊不需要修改主機核心或安裝特殊驅動,也希望減少作業系統維護。
在這些條件下,可以做以下選擇:
| 工作 | 優先選擇 | 判斷原因 | 需要承擔的管理責任 |
|---|---|---|---|
| 常駐 HTTP API | 容器平台 | 已有映像檔與既有執行方式,適合持續運行 | 映像檔更新、健康檢查、擴展與連線管理 |
| 20~40 分鐘資料處理 | 容器平台 | 超過一般 Lambda 單次執行上限,可在需要時啟動容器,完成後停止 | 工作觸發、狀態紀錄、重試與中斷處理 |
| 圖片縮圖 | Lambda | 事件觸發、執行時間短,而且不依賴固定本機狀態 | 事件過濾、冪等性、錯誤處理與並行限制 |
這個案例沒有優先選擇直接在 EC2 上執行應用程式,因為目前沒有需要自行管理主機的明確理由。
前兩項雖然都使用容器平台,但執行方式不同:HTTP API 需要持續運行,資料處理工作則可以在需要時啟動,完成後停止,至於在 ECS 或 EKS 中要如何實作這兩種執行方式,下一篇會再進一步說明。
另外,選擇容器後,還需要決定底層運算容量由誰管理。
如果團隊已經有成熟的 EC2 維運、自動擴展與成本最佳化流程,或需要較高的主機控制權,可以讓容器執行在 EC2 上。
如果希望減少作業系統與底層主機管理,而且工作負載符合 Fargate 的支援範圍,則可以評估 Fargate。
因此,選擇容器平台 和 決定容器底層使用 EC2 或 Fargate,是兩個不同層次的決策。
HTTP API 仍然可以改成 Lambda,但既然已經有可用的映像檔與部署流程,就需要確認改寫後是否能帶來足夠收益。
20~40 分鐘的資料處理工作則因為超過一般 Lambda 函式的執行時間上限,所以優先排除一般 Lambda 執行模式。
在「API 與長時間工作已經容器化、沒有主機層級需求,而且希望降低作業系統維護負擔」的條件下,可以讓這兩類工作交給容器平台執行,再把短時間的圖片事件交給 Lambda。
這代表團隊需要同時維護容器部署與事件驅動兩種執行流程,但不需要為了統一技術選型,強迫所有工作都使用相同的運算方式。
如果後續出現需要特殊驅動、主機權限或其他底層控制的元件,再針對該元件評估 EC2,不必把整套系統一起改成主機部署。
成本也應依不同工作型態分別估算,零星事件未必值得維持常駐容量;長時間、高使用率的服務,則需要比較 EC2、Fargate 與 Lambda 在實際使用量下的成本差異,並納入 Load Balancer、日誌、網路、儲存與預留容量等相關項目。
因此,EC2、容器與 Lambda 並不是整套系統只能三選一,而是應依不同工作負載的執行方式、管理責任與限制分別選擇。
如果決定使用容器,下一步還要回答兩個問題:
這就會帶到 ECS、EKS、EC2 與 Fargate 之間的關係。
下一篇會進一步區分容器編排平台與執行容量,並說明 ECS 中持續運行的服務與一次性工作有什麼差異,再比較什麼情況需要 Kubernetes,以及什麼情況下 ECS 搭配 Fargate 就能滿足需求。